from openpyxl import Workbook, load_workbook
from openpyxl.drawing.image import Image
import re
import os
import zipfile
import tkinter
import tkinter.messagebox


# 判断是否是文件和判断文件是否存在
def isfile_exist(file_path):
    if not os.path.isfile(file_path):
        print("无此文件 ! %s" % file_path)
        return False
    else:
        return True


# 修改指定目录下的文件类型名，将excel后缀名修改为.zip
def change_file_name(file_path, new_type='.zip'):
    if not isfile_exist(file_path):
        return ''
    extend = os.path.splitext(file_path)[1]  # 获取文件拓展名
    if extend != '.xlsx' and extend != '.xls':
        print("不是excel文件 %s" % file_path)
        return False
    file_name = os.path.basename(file_path)  # 获取文件名
    new_name = str(file_name.split('.')[0]) + new_type  # 新的文件名，命名为：xxx.zip

    dir_path = os.path.dirname(file_path)  # 获取文件所在目录
    new_path = os.path.join(dir_path, new_name)  # 新的文件路径
    if os.path.exists(new_path):
        os.remove(new_path)
    os.rename(file_path, new_path)  # 保存新文件，旧文件会替换掉
    return new_path  # 返回新的文件路径，压缩包


# 解压文件
def unzip_file(zipfile_path):
    if not isfile_exist(zipfile_path):
        return False
    if os.path.splitext(zipfile_path)[1] != '.zip':
        print("不是压缩文件 %s" % zipfile_path)
        return False
    file_zip = zipfile.ZipFile(zipfile_path, 'r')
    file_name = os.path.basename(zipfile_path)  # 获取文件名
    zipdir = os.path.join(os.path.dirname(zipfile_path), str(file_name.split('.')[0]))  # 获取文件所在目录
    for files in file_zip.namelist():
        file_zip.extract(files, './临时文件夹')  # 解压到指定文件目录
    file_zip.close()
    return True


# 读取解压后的文件夹，打印图片路径
def read_img(zipfile_path):
    if not isfile_exist(zipfile_path):
        return False
    dir_path = os.path.dirname(zipfile_path)  # 获取文件所在目录
    # file_name = os.path.basename(zipfile_path)  # 获取文件名
    pic_dir = 'xl' + os.sep + 'media'  # excel变成压缩包后，再解压，图片在media目录
    pic_path = os.path.join(dir_path, '临时文件夹', pic_dir)
    file_list = os.listdir(pic_path)
    for file in file_list:
        filepath = os.path.join(pic_path, file)
        yield filepath


# 组合各个函数
def compenent(excel_file_path):
    zip_file_path = change_file_name(excel_file_path)
    if zip_file_path != '':
        if unzip_file(zip_file_path):
            return read_img(zip_file_path)


def add_shopcode(row_ls):
    if '款号' in row_ls:
        row_ls.append('分店')
    else:
        row_ls.append(re.sub(r'\d', '', row_ls[0]))
    return row_ls


def select(excel_file):
    wb_read = load_workbook(excel_file)
    sheet = wb_read['Sheet1']
    ls_sheet = []
    row0 = 1e7
    col0 = 0
    help_ls = []
    first_code = entry2.get().split(';')
    other_code = entry3.get().split(';')
    code_dic = dict(zip(first_code, other_code))
    for r, row in enumerate(sheet.rows):
        each_row = list(map(lambda x: x.value, row))
        if '款号' in each_row:
            row0 = r
            col0 = each_row.index('款号')
            ls_sheet.append(each_row)
        if r > row0:
            if not each_row[col0] in sum(list(map(lambda x: x.split(','), code_dic.values())), []):    # 图片重复款号不再加入help_ls
                if not each_row[col0] in help_ls:
                    help_ls.append(each_row[col0])
                each_row[col0 + 1] = help_ls.index(each_row[col0])
            else:
                for c in first_code:
                    if each_row[col0] in code_dic[c].split(','):
                        fir_c = c
                        break
                each_row[col0 + 1] = help_ls.index(fir_c)
            ls_sheet.append(each_row)
    if col0 > 0:
        ls_sheet = list(map(lambda x: x[col0:], ls_sheet))
    ls_sheet = list(map(add_shopcode, ls_sheet))    # 整理完毕
    wb_read.close()
    # 以下将店分开存入
    code_ls = set(map(lambda x: x[-1], ls_sheet))
    code_ls.remove('分店')
    for i in code_ls:
        wb_write0 = Workbook()
        wb_write0.save(f'{i}.xlsx')
    img_ls = list(compenent(excel_file))    # 图片
    img_num_ls = list(map(lambda x: re.findall(r'image(\d+).+?', x)[0], img_ls))
    for code in code_ls:
        wb_write = load_workbook(f'{code}.xlsx')
        sheet = wb_write['Sheet']
        sheet.column_dimensions['B'].width = 14
        if not ['款号', '图片链接', '颜色', '尺码', '数量'] in [list(map(lambda x: x.value, i)) for i in sheet.rows]:
            sheet.append(['款号', '图片链接', '颜色', '尺码', '数量'])
        for row_ls in ls_sheet[1:]:
            if code in row_ls:
                sheet.append(row_ls[:-1])
                count = sheet.max_row
                sheet.row_dimensions[count].height = 90
                try:
                    path = img_ls[img_num_ls.index(str(row_ls[1] + 1))]
                    img = Image(path)
                    img.width, img.height = (100, 120)
                    sheet.add_image(img, f'B{count}')
                except:
                    tkinter.messagebox.showwarning('警告', '存在不同款号对应相同图片，导致部分款号、图片不匹配\n请输入相同图片的款号')
        count = sheet.max_row+1
        sheet[f'D{count}'] = '总件数'
        sheet[f'E{count}'] = '=SUM(E2:E' + str(count-1) + ')'
        wb_write.save(f'{code}.xlsx')

def main():
    file = entry1.get()
    portion = os.path.splitext(file)
    select(file)
    os.rename(file[:-5] + '.zip', portion[0] + '.xlsx')
    print('筛选完成')

if __name__ == '__main__':
    root = tkinter.Tk()
    root.title('表格筛选')
    root['width'] = 300
    root['height'] = 200
    label1 = tkinter.Label(root, text='请输入待筛选表格名称')
    label1.place(x=30, y=20, width=150, height=30)
    entry1 = tkinter.Entry(root)
    entry1.place(x=30, y=50, width=150, height=30)
    button_start = tkinter.Button(root, text='开始', command=main)
    button_start.place(x=190, y=50, width=60, height=30)
    label2 = tkinter.Label(root, text='出现相同图片的第一个款号')
    label2.place(x=30, y=90, width=150, height=30)
    entry2 = tkinter.Entry(root)
    entry2.place(x=200, y=90, width=60, height=30)
    label3 = tkinter.Label(root, text='出现相同图片的后续所有款号\n多个请用","隔开')
    label3.place(x=30, y=130, width=160, height=50)
    entry3 = tkinter.Entry(root)
    entry3.place(x=200, y=130, width=60, height=30)
    root.mainloop()